package org.dromara.assets.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.binance.connector.client.spot.websocket.api.model.AvgPriceRequest;
import com.binance.connector.client.spot.websocket.api.model.AvgPriceResponse;
import lombok.extern.slf4j.Slf4j;
import org.dromara.assets.domain.AssetsTradePlan;
import org.dromara.assets.mapper.AssetsTradePlanMapper;
import org.dromara.common.satoken.core.dao.PlusSaTokenDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Slf4j
@Service
public class TradePlanService {

    @Autowired
    private AssetsTradePlanMapper assetsTradePlanMapper;

    public void processTradePlans() {
        List<AssetsTradePlan> plans = assetsTradePlanMapper.selectList(new LambdaQueryWrapper<>());
        for (AssetsTradePlan plan : plans) {
            processPlan(plan);
        }
    }

    private void processPlan(AssetsTradePlan plan) {
        switch (plan.getState()) {
            case 1:
                processState1(plan);
                break;
            case 2:
                processState2(plan);
                break;
            case 3:
                processState3(plan);
                break;
            case 4:
                processState4(plan);
                break;
            case 5:
                processState5(plan);
                break;
        }
    }

    private void processState1(AssetsTradePlan plan) {
        // 模拟获取当前币价
        BigDecimal currentPrice = getCurrentPrice(plan.getSymbol());
        plan.setCurrentPrice(currentPrice);
        log.info("check price result,trigger price is {},current price is {}", plan.getTriggerPrice(), currentPrice);
        if (currentPrice.compareTo(plan.getTriggerPrice()) < 0) {
            plan.setState(2);
            updateState(plan);
            processPlan(plan);
        }
    }

    /**
     * 处理是否需要赎回操作
     **/
    private void processState2(AssetsTradePlan plan) {
        log.info("begin to processState2");
        if (plan.getIsRedeemNeeded()) {
            plan.setState(21);
            updateState(plan);
            // 进行赎回操作
            redeem(plan);
            plan.setState(3);
            updateState(plan);
            processPlan(plan);
        } else {
            plan.setState(3);
            updateState(plan);
            processPlan(plan);
        }
    }

    private void processState3(AssetsTradePlan plan) {
        log.info("begin to processState3");
        if (plan.getIsSwapNeeded()) {
            plan.setState(31);
            updateState(plan);
            // 进行币币交换操作
            swap(plan);
            plan.setState(4);
            updateState(plan);
            processPlan(plan);
        } else {
            plan.setState(4);
            updateState(plan);
            processPlan(plan);
        }
    }

    private void processState4(AssetsTradePlan plan) {
        log.info("begin to processState4");
        try {
            // 下单操作
            placeOrder(plan);
            plan.setState(5);
            updateState(plan);
            processPlan(plan);
        } catch (Exception e) {
            log.error("placeOrder error", e);
            plan.setState(43);
            updateState(plan);
        }
    }

    private void processState5(AssetsTradePlan plan) {
        log.info("begin to processState5");
        if ("COMPLETED".equals(plan.getTransactionStatus())) {
            plan.setState(52);
            // 写交易流水
            writeTransactionLog(plan);
            plan.setState(10);
            updateState(plan);
        } else {
            BigDecimal currentPrice = getCurrentPrice(plan.getSymbol());
            plan.setCurrentPrice(currentPrice);
            if (currentPrice.compareTo(BigDecimal.valueOf(100)) < 0) { // 假设到达100发送邮件
                sendEmail(plan);
            }
        }
    }

    private BigDecimal getCurrentPrice(String symbol) {
        // 模拟获取当前币价
        try {
            AvgPriceRequest request = new AvgPriceRequest().symbol(symbol);
            CompletableFuture<AvgPriceResponse> responseCompletableFuture =
                    BinanceWebSocketWithNew.api.avgPrice(request);
            String price = responseCompletableFuture.get().getResult().getPrice();
            return new BigDecimal(price);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    private void redeem(AssetsTradePlan plan) {
        // 实现赎回逻辑
    }

    private void swap(AssetsTradePlan plan) {
        // 实现币币交换逻辑
    }

    private void placeOrder(AssetsTradePlan plan) {
        // 实现下单逻辑
    }

    private void writeTransactionLog(AssetsTradePlan plan) {
        // 实现写交易流水逻辑
    }

    private void sendEmail(AssetsTradePlan plan) {
        // 实现发送邮件逻辑
    }

    private void updateState(AssetsTradePlan plan) {
        plan.setUpdatedAt(LocalDateTime.now());
        plan.setRemarks(plan.getRemarks() + "->" + plan.getState());
        assetsTradePlanMapper.update(null, new LambdaUpdateWrapper<AssetsTradePlan>()
                .set(AssetsTradePlan::getUpdatedAt, plan.getUpdatedAt())
                .set(AssetsTradePlan::getState, plan.getState())
                .set(AssetsTradePlan::getRemarks, plan.getRemarks())
                .eq(AssetsTradePlan::getId, plan.getId()));
    }
}